﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace SpaceWars
{
    // Generic class for an object represented in the game
    public class GameObject
    {
        public Texture2D sprite;
        public Vector2 loc, size, vel;
        public double angle;
        public bool alive;
        public GameObject()
        {
            sprite = null;
            loc = size = vel = new Vector2(-500.0f, -500.0f);
            angle = 0.0;
            alive = false;
        }
        public GameObject(Texture2D tex)
        {
            sprite = tex;
            loc = size = vel = Vector2.Zero;
            angle = 0.0;
            alive = false;
        }
        public GameObject(Texture2D tex, Vector2 location, Vector2 spriteSize, Vector2 velocity, double rotateAngle, bool isAlive)
        {
            sprite = tex;
            loc = location;
            size = spriteSize;
            vel = velocity;
            angle = rotateAngle;
            alive = isAlive;
        }
        public virtual void move( double elapsedTime)
        {
            Rectangle screen = new Rectangle(0, 0, 800, 600);
            loc += vel * (float)elapsedTime;
            if (!screen.Contains((int)loc.X, (int)loc.Y))
            {
                alive = false;
                loc = new Vector2(-500.0f, -500.0f);
            }
        }
        public virtual void draw(SpriteBatch sb)
        {
            sb.Begin(SpriteBlendMode.None, SpriteSortMode.FrontToBack, SaveStateMode.None);
            sb.Draw(sprite, loc, new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.5f);
            sb.End();
        }
        public bool collides(GameObject that)
        {
            if (this.alive && that.alive)
            {
                Rectangle a = new Rectangle((int)(loc.X - (size.X / 2.0f)), (int)(loc.Y - (size.Y / 2.0f)), (int)size.X, (int)size.Y);
                Rectangle b = new Rectangle((int)(that.loc.X - (that.size.X / 2.0f)), (int)(that.loc.Y - (that.size.Y / 2.0f)), (int)that.size.X, (int)that.size.Y);
                return a.Intersects(b);
            }
            return false;
        }
        public void kill()
        {
            alive = false;
            vel = Vector2.Zero;
            loc = new Vector2(-500.0f, -500.0f);
        }
    }
    // Specialized instance of GameObject for the players ship
    public class Ship : GameObject
    {
        public int health, numBullets;
        public Ship() : base() { health = 4; numBullets = 100; }
        public Ship(Texture2D tex)
        {
            sprite = tex;
            loc = new Vector2(400.0f, 300.0f);
            size = new Vector2(32.0f, 32.0f);
            vel = Vector2.Zero;
            angle = Math.PI / 2;
            alive = true;
            health = 4;
            numBullets = 100;
        }
        public override void move( double elapsedTime )
        {
            float tmp = vel.X * vel.X + vel.Y * vel.Y;
            // Limit maximum speed to 200 pixels per second
            if (tmp > 40000.0f)
                vel *= (40000.0f / tmp);
            vel *= 0.8f;
            loc += vel * (float)elapsedTime;
            if (loc.Y >= 600.0f)
                loc.Y = 600.0f;
            if (loc.Y <= 0.0f)
                loc.Y = 0.0f;
            if (loc.X >= 800.0f)
                loc.X = 800.0f;
            if (loc.X <= 0.0f)
                loc.X = 0.0f;
        }
        public override void draw(SpriteBatch sb)
        {
            Vector3 color = new Vector3((float)numBullets / 100.0f, 1.0f, 1.0f);
            sb.Begin(SpriteBlendMode.None, SpriteSortMode.FrontToBack, SaveStateMode.None);
            sb.Draw(sprite, loc, new Rectangle(0, 0, (int)size.X, (int)size.Y), new Color(color), (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.5f);
            sb.End();
        }
    }
    // Specialized instance of GameObject for the enemy ships
    public class Enemy : GameObject
    {
        public int type;
        public Enemy() : base() { type = 1; }
        public Enemy(Texture2D tex) : base(tex) { type = 1; }
        public Enemy(Texture2D tex, Vector2 location, Vector2 spriteSize, Vector2 velocity, double rotateAngle, bool isAlive) :
            base(tex, location, spriteSize, velocity, rotateAngle, isAlive) { type = 1; }
        public Enemy(Texture2D tex, Vector2 location, Vector2 spriteSize, Vector2 velocity, double rotateAngle, bool isAlive, int t) :
            base(tex, location, spriteSize, velocity, rotateAngle, isAlive) { type = t; }
        public override void move( double elapsedTime )
        {
        }
    }

    public class Background : GameObject
    {
        public Background() : base(){}
        public Background(Texture2D tex) : base(tex){}
        public Background(Texture2D tex, Vector2 location, Vector2 spriteSize, Vector2 velocity, double rotateAngle, bool isAlive) :
            base(tex, location, spriteSize, velocity, rotateAngle, isAlive) {}
        public override void move( double elapsedTime )
        {
            float tmp = vel.X * vel.X + vel.Y * vel.Y;
            // Limit maximum speed to 200 pixels per second
            if (tmp > 40000.0f)
                vel *= (40000.0f / tmp);
            vel *= 0.8f;
            loc += vel * (float)elapsedTime;
            if (loc.Y >= 600.0f)
                loc.Y = 600.0f;
            if (loc.Y <= 0.0f)
                loc.Y = 0.0f;
            if (loc.X >= 800.0f)
                loc.X = 800.0f;
            if (loc.X <= 0.0f)
                loc.X = 0.0f;
        }
        public override void draw(SpriteBatch sb)
        {
            sb.Begin(SpriteBlendMode.None, SpriteSortMode.FrontToBack, SaveStateMode.None);
            sb.Draw(sprite, loc, new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            sb.Draw(sprite, loc - new Vector2(size.X, 0.0f), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(size.X, size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(size.X, -size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            sb.Draw(sprite, loc - new Vector2(-size.X, 0.0f), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(-size.X, size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(-size.X, -size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(0.0f, size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            //sb.Draw(sprite, loc - new Vector2(0.0f, -size.Y), new Rectangle(0, 0, (int)size.X, (int)size.Y), Color.White, (float)angle, size / 2.0f, 1.0f, SpriteEffects.None, 0.0f);
            sb.End();
        }
    }
}